package com.neuedu.corejava.ch13.homework;
/**
 * 20190815早上
 * 死锁
 * @author admin
 *
 */
public class HomeWork5 {
	//只要是Object类或其子类都可以作为一个锁
		private static final Object LOCKED=new Object();
		//注意：在程序中可能有多把锁，需要多同一个资源进行锁定，必须使用同一把锁
		private static final Object LOCKED2=new Object();
		private int count = 0;

		public  void add(int threadId) {
			/**
			 * 代码块锁，可以使用一个对象锁定一个代码块，在代码块中控制对某个资源的共享
			 * 如何加锁：对有线程共享安全的数据进行加锁，使用方法所或代码块锁
			 */
			synchronized(LOCKED){
				count++;
				System.out.println(threadId + "," + count);
				//在同步块中调用其它锁的方法--如果互相调用则容易出现死锁
				desc(threadId);
			}
			
		}

		public  void desc(int threadId) {
			synchronized(LOCKED2){
				count--;
				System.out.println(threadId + "," + count);
				//在同步块中调用其它锁的方法--如果互相调用则容易出现死锁
				add(threadId);
			}
		}

		class AddClass implements Runnable {
			private int threadId = 0;

			private AddClass(int id) {
				this.threadId = id;
			}

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 50; i++) {
					add(threadId);
					/*
					 * try { Thread.sleep(1); } catch (InterruptedException e) { //
					 * TODO Auto-generated catch block e.printStackTrace(); }
					 */
				}
			}

		}

		class DescClass implements Runnable {
			private int threadId = 0;

			private DescClass(int id) {
				this.threadId = id;
			}

			@Override
			public void run() {
				// TODO Auto-generated method stub
				for (int i = 0; i < 50; i++) {
					desc(threadId);

					/*
					 * try { Thread.sleep(1); } catch (InterruptedException e) { //
					 * TODO Auto-generated catch block e.printStackTrace(); }
					 */
				}
			}

		}

		public static void main(String[] args) {
			HomeWork5 homeWork5 = new HomeWork5();
			AddClass addClass1 = homeWork5.new AddClass(1);
			AddClass addClass2 = homeWork5.new AddClass(2);

			DescClass descClass1 = homeWork5.new DescClass(3);
			DescClass descClass2 = homeWork5.new DescClass(4);

			new Thread(addClass1).start();
			new Thread(addClass2).start();
			new Thread(descClass1).start();
			new Thread(descClass2).start();
		}
}
